package com.ruoyi.inspection.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.HeFengTianQiApiConstants;
import com.ruoyi.common.utils.http.HttpClientUtil;
import com.ruoyi.inspection.service.WeatherService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;

import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/**
 * 天气Service业务层处理
 *
 * @author ruoyi
 * @date 2024-06-18
 */
@Service
public class WeatherServiceImpl implements WeatherService {
    /**
     * 和风天气的一日天气指数预报
     *
     * @return
     */
    @Override
    public JSONObject indicesForecastOneDay(String location, String type) throws Exception {
        String domain = HeFengTianQiApiConstants.domain_indices_forecast_1day;
        Map<String, Object> params = new HashMap<>();
        params.put("location", location);
        params.put("type", type);
        String heFengTianQiSign = getHeFengTianQiSign(params);
        params.put("sign", heFengTianQiSign);
        String result = HttpClientUtil.doGet(domain, params, Constants.UTF8);
        return JSONObject.parseObject(result);
    }

    /**
     * 获取和风天气api请求的签名
     * 参考网页地址：https://dev.qweather.com/docs/resource/signature-auth/#create-signature
     * publicid: 公共ID，每个KEY都对应一个公共ID，可在控制台查看(即控制台中创建项目后生成的publicid)
     * <p>
     * t: 时间戳，秒级
     * <p>
     * sign: 数字签名(即控制台中创建项目后生成的key)
     *
     * @return
     */
    public String getHeFengTianQiSign(Map<String, Object> params) throws Exception {
        // 获取当前时间的毫秒时间戳
        long currentTimeMillis = System.currentTimeMillis();
        // 转换为秒级别的时间戳
        long currentTimeSeconds = currentTimeMillis / 1000;
        String key = "6d09fd1a94fa4303aa3dd69e2e391842";
        params.put("publicid", "HE2406181342251866");
        params.put("t", String.valueOf(currentTimeSeconds));
        String signature = getSignature(params, key);
        return signature;
    }

    /**
     * 和风天气签名生成算法-JAVA版本
     *
     * @param params 请求参数集，所有参数必须已转换为字符串类型
     * @param secret 签名密钥（用户的认证key）
     * @return 签名
     * @throws Exception
     */
    public static String getSignature(Map<String, Object> params, String secret) throws Exception {
        //先将key为sign的过滤以及值为空的过滤
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            if ("sign".equals(entry.getKey())) {
                params.remove(entry.getKey());
            } else if (ObjectUtils.isEmpty(entry.getValue())) {
                params.remove(entry.getKey());
            }
        }
        // 先将参数以其参数名的字典序升序进行排序
        Map<String, Object> sortedParams = new TreeMap<>(params);
        Set<Map.Entry<String, Object>> entrys = sortedParams.entrySet();

        // 遍历排序后的字典，将所有参数按"key=value"格式拼接在一起
        StringBuilder baseString = new StringBuilder();
        for (Map.Entry<String, Object> param : entrys) {
            //sign参数 和 空值参数 不加入算法
            baseString.append(param.getKey().trim()).append("=").append(param.getValue().toString().trim()).append("&");
        }
        if (baseString.length() > 0) {
            baseString.deleteCharAt(baseString.length() - 1).append(secret);
        }
        // 使用MD5对待签名串求签
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] bytes = md5.digest(baseString.toString().getBytes("UTF-8"));
            return new String(encodeHex(bytes));
        } catch (GeneralSecurityException ex) {
            throw ex;
        }
    }

    public static char[] encodeHex(byte[] data) {
        int l = data.length;
        char[] out = new char[l << 1];
        int i = 0;
        char[] toDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
        for (int var5 = 0; i < l; ++i) {
            out[var5++] = toDigits[(240 & data[i]) >>> 4];
            out[var5++] = toDigits[15 & data[i]];
        }
        return out;
    }

    /**
     * 格点逐小时天气预报24h
     *
     * @param location 位置：经度纬度中间拿逗号连接
     * @return
     * @throws Exception
     */
    @Override
    public JSONObject gridWeather24h(String location) throws Exception {
        String domain = HeFengTianQiApiConstants.domain_grid_weather_24h;
        Map<String, Object> params = new HashMap<>();
        params.put("location", location);
        String heFengTianQiSign = getHeFengTianQiSign(params);
        params.put("sign", heFengTianQiSign);
        String result = HttpClientUtil.doGet(domain, params, Constants.UTF8);
        return JSONObject.parseObject(result);
    }

    /**
     * 每日天气预报 3天预报
     * @param location
     * @return
     * @throws Exception
     */
    @Override
    public JSONObject weather3d(String location) throws Exception {
        String domain = HeFengTianQiApiConstants.domain_weather_3d;
        Map<String, Object> params = new HashMap<>();
        params.put("location", location);
        String heFengTianQiSign = getHeFengTianQiSign(params);
        params.put("sign", heFengTianQiSign);
        String result = HttpClientUtil.doGet(domain, params, Constants.UTF8);
        return JSONObject.parseObject(result);
    }
}
